using Digitalmes.Application.Sys.Users.Queries;

namespace Digitalmes.WebApi.Endpoints;

/// <summary>
/// 动态路由终结点。
/// </summary>
public sealed class RouteEndpoint : EndpointGroupBase
{
    public override void Map(WebApplication app)
    {
        app.MapGroup(this)
            .RequireAuthorization()
            .MapGet(GetRoutesAsync, "async-routes");
    }

    [EndpointDescription("获取动态路由信息")]
    public async Task<IApiResult> GetRoutesAsync(ICurrentUser currentUser, ISender sender)
    {
        // 路由结构：
        // component:
        //  name: string;
        //  path: string;
        //  component?: string; // views 目录下组件路径
        //  meta: {};
        //
        // meta:
        //  title: string; #标题名称
        //  icon?: string; #图标（菜单/tab）
        //  iframeSrc?: string; #iframe 地址
        //  link?: string; #外链-跳转路径
        //  keepAlive?: boolean; #开启KeepAlive缓存
        //  hideInMenu?: boolean; #当前路由在菜单中不展现
        //  hideChildrenInMenu?: boolean; #当前路由的子级在菜单中不展现
        //  hideInTab?: boolean; #当前路由在标签页不展现
        //  openInNewWindow?: boolean; #在新窗口打开
        //  authority?: string[]; #权限，指定哪些角色可见，如果不配置，默认可见
        //  order?: number; #用于路由->菜单排序

        if (currentUser.UserId is null)
        {
            return ApiResult.Bad();
        }

        var menuList = (await sender.Send(new GetMenusOfUserQuery(currentUser.UserId.Value))).Value;

        IEnumerable<RouteViewModel> FormatRoute(long parentId)
        {
            foreach (var menu in menuList.Where(m => m.ParentId == parentId).OrderBy(m => m.Order))
            {
                RouteViewModel route = new()
                {
                    Path = menu.Path,
                    Name = menu.Name,
                    Component = menu.Component,
                    Meta = new RouteMetaViewModel
                    {
                        Title = menu.Title,
                        Icon = menu.Icon,
                        IframeSrc = menu.IframeSrc,
                        Link = menu.Link,
                        AffixTab = menu.AffixTab,
                        KeepAlive = menu.KeepAlive,
                        HideInMenu = menu.HideInTab,
                        HideChildrenInMenu = menu.HideChildrenInMenu,
                        HideInTab = menu.HideInTab,
                        OpenInNewWindow = menu.OpenInNewWindow,
                        Authority = menu.Authority,
                        Order = menu.Order,
                    },
                };

                // 没有 Children 时，默认值为 null。
                var children = FormatRoute(menu.Id).ToList();
                if (children.Count > 0)
                {
                    route.Children = children;
                }

                yield return route;
            }
        }

        var routes = FormatRoute(0);
        return ApiResult.Ok(routes);
    }
}
